home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
LANG
/
LISP
/
FOOLS
/
!Fl
/
scm
/
macros
< prev
next >
Wrap
Text File
|
1991-10-16
|
2KB
|
90 lines
;;; extend-syntax macros
(require 'extend)
(provide 'macros)
(extend-syntax (do)
[(do ([var init . step] ...) (test texp ...) dexp ...)
(andmap symbol? '(var ...))
(with ([do-loop (gensym)]
[(do-step ...)
(map (lambda (x y)
(if (null? y) x (car y)))
'(var ...) '(step ...))])
(letrec ((do-loop
(lambda (var ...)
(if test
(begin texp ...)
(begin dexp ... (do-loop do-step ...))))))
(do-loop init ...)))])
(extend-syntax (record-case else)
[(record-case val (else exp ...))
(begin exp ...)]
[(record-case val clause ...)
(pair? 'val)
(with ([temp (gensym)])
(let ([temp val])
(record-case temp clause ...)))]
[(record-case val (key idspec exp ...) more ...)
(with ([bindings
(let parse ([pat 'idspec] [acc '(cdr val)] [recs '()])
(cond ((symbol? pat)
(cons (list pat acc) recs))
((pair? pat)
(parse (car pat)
`(car ,acc)
(parse (cdr pat)
`(cdr ,acc)
recs)))
(else recs)))]
[same? (if (symbol? 'key) eq? eqv?)])
(if (same? (car val) 'key)
(let bindings exp ...)
(record-case val more ...)))]
[(record-case val) #f])
(extend-syntax (define-structure)
;; from "The Scheme Programming Language" by R. Kent Dybvig
[(define-structure (name id1 ...))
; XXX: (begin ...) necessary to avoid macro short-circuiting
(begin (define-structure (name id1 ...) ()))]
[(define-structure (name id1 ...) ([id2 val] ...))
(with ([constructor
(string->symbol (string-append "make-" 'name))]
[predicate
(string->symbol (string-append 'name "?"))]
[(access ...)
(map (lambda (x)
(string->symbol (string-append 'name "-" x)))
'(id1 ... id2 ...))]
[(assign ...)
(map (lambda (x)
(string->symbol
(string-append "set-" 'name "-" x "!")))
'(id1 ... id2 ...))]
[count (length '(name id1 ... id2 ...))])
(with ([(index ...)
(let f ([i 1])
(if (= i 'count)
'()
(cons i (f (+ i 1)))))])
(begin
(define constructor
(lambda (id1 ...)
(let* ([id2 val] ...)
(vector 'name id1 ... id2 ...))))
(define predicate
(lambda (obj)
(and (vector? obj)
(= (vector-length obj) count)
(eq? (vector-ref obj 0) 'name))))
(define access
(lambda (obj)
(vector-ref obj index)))
...
(define assign
(lambda (obj newval)
(vector-set! obj index newval)))
...)))])